#include "data_point.h"
#include <sstream>
#include <regex>
#include <chrono>

namespace kwdb {

DataPoint::DataPoint(const std::string& measurement)
    : measurement_(measurement)
    , timestamp_(std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count()) {
}

DataPoint::DataPoint(const std::string& measurement, int64_t timestamp)
    : measurement_(measurement)
    , timestamp_(timestamp) {
}

DataPoint& DataPoint::addTag(const std::string& key, const std::string& value) {
    tags_[key] = value;
    return *this;
}

DataPoint& DataPoint::addField(const std::string& key, const std::string& value) {
    fields_[key] = "\"" + value + "\"";
    return *this;
}

DataPoint& DataPoint::addField(const std::string& key, int64_t value) {
    fields_[key] = std::to_string(value);
    return *this;
}

DataPoint& DataPoint::addField(const std::string& key, double value) {
    fields_[key] = std::to_string(value);
    return *this;
}

DataPoint& DataPoint::addField(const std::string& key, bool value) {
    fields_[key] = value ? "true" : "false";
    return *this;
}

DataPoint& DataPoint::setTimestamp(int64_t timestamp) {
    timestamp_ = timestamp;
    return *this;
}

std::string DataPoint::toLineProtocol() const {
    std::ostringstream oss;
    
    // 添加measurement
    oss << escapeString(measurement_);
    
    // 添加tags
    if (!tags_.empty()) {
        oss << ",";
        bool first = true;
        for (const auto& tag : tags_) {
            if (!first) {
                oss << ",";
            }
            oss << escapeString(tag.first) << "=" << escapeString(tag.second);
            first = false;
        }
    }
    
    // 添加fields
    oss << " ";
    bool first = true;
    for (const auto& field : fields_) {
        if (!first) {
            oss << ",";
        }
        oss << escapeString(field.first) << "=" << field.second;
        first = false;
    }
    
    // 添加时间戳
    oss << " " << timestamp_;
    
    return oss.str();
}

std::string DataPoint::escapeString(const std::string& str) const {
    std::string result = str;
    
    // 转义特殊字符
    result = std::regex_replace(result, std::regex("([, ])"), "\\$1");
    result = std::regex_replace(result, std::regex("="), "\\=");
    
    return result;
}

} // namespace kwdb
